using System;
using System.Collections.Generic;
using System.Linq;

namespace MT5Trade.Models
{
    /// <summary>
    /// 风险控制参数矩阵 - 实现文档9.5节要求
    /// 统一管理所有风险参数限制，提供分级风控策略
    /// 基于市场状态动态调整风险参数边界
    /// </summary>
    public class RiskControlMatrix
    {
        #region 风险等级定义 - 基于文档9.5节

        /// <summary>
        /// 风险等级枚举
        /// </summary>
        public enum RiskLevel
        {
            Conservative = 0,  // 保守型 - 最低风险
            Moderate = 1,      // 稳健型 - 中等风险
            Aggressive = 2,    // 激进型 - 高风险
            Emergency = 3      // 应急型 - 风险控制模式
        }

        /// <summary>
        /// 市场状态（与AdaptiveHedgeOptimizer同步）
        /// </summary>
        public enum MarketState
        {
            Normal,    // 正常市况
            Warning,   // 警戒状态
            Danger     // 危险状态
        }

        #endregion

        #region 风控参数限制矩阵 - 基于文档9.5节表格

        /// <summary>
        /// 风控参数配置
        /// </summary>
        public class RiskParameters
        {
            // 仓位控制
            public double MinPositionSize { get; set; }
            public double MaxPositionSize { get; set; }
            
            // 杠杆控制
            public double MinLeverage { get; set; }
            public double MaxLeverage { get; set; }
            
            // 止损控制
            public double MinStopLoss { get; set; }
            public double MaxStopLoss { get; set; }
            
            // 敞口控制
            public double MinGapRatio { get; set; }
            public double MaxGapRatio { get; set; }
            
            // 风险指标
            public double MaxVaR95 { get; set; }      // 最大VaR(95%置信度)
            public double MaxCVaR95 { get; set; }     // 最大CVaR(95%置信度)
            public double MaxDrawdown { get; set; }    // 最大回撤
            public double MinSharpeRatio { get; set; } // 最小夏普比率
            
            // 破产概率
            public double MaxBankruptcyProbability { get; set; }
            
            // 执行控制
            public int MaxRetryCount { get; set; }     // 最大重试次数
            public int MaxConcurrentTrades { get; set; } // 最大并发交易数
            public double MinMarginLevel { get; set; }   // 最小保证金水平
        }

        // 预定义风控参数矩阵
        private static readonly Dictionary<(RiskLevel, MarketState), RiskParameters> ParameterMatrix = 
            new Dictionary<(RiskLevel, MarketState), RiskParameters>
        {
            // 保守型策略
            { (RiskLevel.Conservative, MarketState.Normal), new RiskParameters
                {
                    MinPositionSize = 0.01, MaxPositionSize = 0.5,
                    MinLeverage = 10, MaxLeverage = 50,
                    MinStopLoss = 0.01, MaxStopLoss = 0.03,
                    MinGapRatio = 0, MaxGapRatio = 0.1,
                    MaxVaR95 = 0.05, MaxCVaR95 = 0.08,
                    MaxDrawdown = 0.1, MinSharpeRatio = 1.5,
                    MaxBankruptcyProbability = 0.01,
                    MaxRetryCount = 3, MaxConcurrentTrades = 5,
                    MinMarginLevel = 200
                }
            },
            { (RiskLevel.Conservative, MarketState.Warning), new RiskParameters
                {
                    MinPositionSize = 0.01, MaxPositionSize = 0.3,
                    MinLeverage = 10, MaxLeverage = 30,
                    MinStopLoss = 0.005, MaxStopLoss = 0.02,
                    MinGapRatio = 0, MaxGapRatio = 0.05,
                    MaxVaR95 = 0.03, MaxCVaR95 = 0.05,
                    MaxDrawdown = 0.05, MinSharpeRatio = 2.0,
                    MaxBankruptcyProbability = 0.005,
                    MaxRetryCount = 2, MaxConcurrentTrades = 3,
                    MinMarginLevel = 300
                }
            },
            { (RiskLevel.Conservative, MarketState.Danger), new RiskParameters
                {
                    MinPositionSize = 0.01, MaxPositionSize = 0.1,
                    MinLeverage = 10, MaxLeverage = 20,
                    MinStopLoss = 0.003, MaxStopLoss = 0.01,
                    MinGapRatio = 0, MaxGapRatio = 0,
                    MaxVaR95 = 0.02, MaxCVaR95 = 0.03,
                    MaxDrawdown = 0.03, MinSharpeRatio = 3.0,
                    MaxBankruptcyProbability = 0.001,
                    MaxRetryCount = 1, MaxConcurrentTrades = 1,
                    MinMarginLevel = 500
                }
            },
            
            // 稳健型策略
            { (RiskLevel.Moderate, MarketState.Normal), new RiskParameters
                {
                    MinPositionSize = 0.1, MaxPositionSize = 1.0,
                    MinLeverage = 50, MaxLeverage = 200,
                    MinStopLoss = 0.01, MaxStopLoss = 0.05,
                    MinGapRatio = 0, MaxGapRatio = 0.3,
                    MaxVaR95 = 0.1, MaxCVaR95 = 0.15,
                    MaxDrawdown = 0.2, MinSharpeRatio = 1.0,
                    MaxBankruptcyProbability = 0.05,
                    MaxRetryCount = 5, MaxConcurrentTrades = 10,
                    MinMarginLevel = 100
                }
            },
            { (RiskLevel.Moderate, MarketState.Warning), new RiskParameters
                {
                    MinPositionSize = 0.05, MaxPositionSize = 0.5,
                    MinLeverage = 30, MaxLeverage = 100,
                    MinStopLoss = 0.01, MaxStopLoss = 0.03,
                    MinGapRatio = 0, MaxGapRatio = 0.15,
                    MaxVaR95 = 0.07, MaxCVaR95 = 0.1,
                    MaxDrawdown = 0.15, MinSharpeRatio = 1.2,
                    MaxBankruptcyProbability = 0.03,
                    MaxRetryCount = 3, MaxConcurrentTrades = 5,
                    MinMarginLevel = 150
                }
            },
            { (RiskLevel.Moderate, MarketState.Danger), new RiskParameters
                {
                    MinPositionSize = 0.01, MaxPositionSize = 0.2,
                    MinLeverage = 20, MaxLeverage = 50,
                    MinStopLoss = 0.005, MaxStopLoss = 0.02,
                    MinGapRatio = 0, MaxGapRatio = 0.05,
                    MaxVaR95 = 0.05, MaxCVaR95 = 0.07,
                    MaxDrawdown = 0.1, MinSharpeRatio = 1.5,
                    MaxBankruptcyProbability = 0.01,
                    MaxRetryCount = 2, MaxConcurrentTrades = 2,
                    MinMarginLevel = 200
                }
            },
            
            // 激进型策略
            { (RiskLevel.Aggressive, MarketState.Normal), new RiskParameters
                {
                    MinPositionSize = 0.5, MaxPositionSize = 2.0,
                    MinLeverage = 100, MaxLeverage = 500,
                    MinStopLoss = 0.02, MaxStopLoss = 0.1,
                    MinGapRatio = 0, MaxGapRatio = 0.5,
                    MaxVaR95 = 0.2, MaxCVaR95 = 0.3,
                    MaxDrawdown = 0.4, MinSharpeRatio = 0.5,
                    MaxBankruptcyProbability = 0.1,
                    MaxRetryCount = 10, MaxConcurrentTrades = 20,
                    MinMarginLevel = 50
                }
            },
            { (RiskLevel.Aggressive, MarketState.Warning), new RiskParameters
                {
                    MinPositionSize = 0.2, MaxPositionSize = 1.0,
                    MinLeverage = 50, MaxLeverage = 200,
                    MinStopLoss = 0.015, MaxStopLoss = 0.05,
                    MinGapRatio = 0, MaxGapRatio = 0.3,
                    MaxVaR95 = 0.15, MaxCVaR95 = 0.2,
                    MaxDrawdown = 0.25, MinSharpeRatio = 0.8,
                    MaxBankruptcyProbability = 0.07,
                    MaxRetryCount = 5, MaxConcurrentTrades = 10,
                    MinMarginLevel = 75
                }
            },
            { (RiskLevel.Aggressive, MarketState.Danger), new RiskParameters
                {
                    MinPositionSize = 0.05, MaxPositionSize = 0.3,
                    MinLeverage = 30, MaxLeverage = 100,
                    MinStopLoss = 0.01, MaxStopLoss = 0.03,
                    MinGapRatio = 0, MaxGapRatio = 0.1,
                    MaxVaR95 = 0.1, MaxCVaR95 = 0.15,
                    MaxDrawdown = 0.15, MinSharpeRatio = 1.0,
                    MaxBankruptcyProbability = 0.03,
                    MaxRetryCount = 3, MaxConcurrentTrades = 3,
                    MinMarginLevel = 100
                }
            },
            
            // 应急模式（所有风险等级在紧急情况下的统一参数）
            { (RiskLevel.Emergency, MarketState.Normal), new RiskParameters
                {
                    MinPositionSize = 0, MaxPositionSize = 0.1,
                    MinLeverage = 10, MaxLeverage = 20,
                    MinStopLoss = 0.003, MaxStopLoss = 0.01,
                    MinGapRatio = 0, MaxGapRatio = 0,
                    MaxVaR95 = 0.01, MaxCVaR95 = 0.02,
                    MaxDrawdown = 0.02, MinSharpeRatio = 5.0,
                    MaxBankruptcyProbability = 0.001,
                    MaxRetryCount = 0, MaxConcurrentTrades = 0,
                    MinMarginLevel = 1000
                }
            },
            { (RiskLevel.Emergency, MarketState.Warning), new RiskParameters
                {
                    MinPositionSize = 0, MaxPositionSize = 0.05,
                    MinLeverage = 10, MaxLeverage = 10,
                    MinStopLoss = 0.002, MaxStopLoss = 0.005,
                    MinGapRatio = 0, MaxGapRatio = 0,
                    MaxVaR95 = 0.005, MaxCVaR95 = 0.01,
                    MaxDrawdown = 0.01, MinSharpeRatio = 10.0,
                    MaxBankruptcyProbability = 0.0001,
                    MaxRetryCount = 0, MaxConcurrentTrades = 0,
                    MinMarginLevel = 2000
                }
            },
            { (RiskLevel.Emergency, MarketState.Danger), new RiskParameters
                {
                    MinPositionSize = 0, MaxPositionSize = 0,
                    MinLeverage = 0, MaxLeverage = 0,
                    MinStopLoss = 0, MaxStopLoss = 0,
                    MinGapRatio = 0, MaxGapRatio = 0,
                    MaxVaR95 = 0, MaxCVaR95 = 0,
                    MaxDrawdown = 0, MinSharpeRatio = double.MaxValue,
                    MaxBankruptcyProbability = 0,
                    MaxRetryCount = 0, MaxConcurrentTrades = 0,
                    MinMarginLevel = double.MaxValue
                }
            }
        };

        #endregion

        #region 私有字段

        private RiskLevel _currentRiskLevel;
        private MarketState _currentMarketState;
        private RiskParameters _currentParameters;
        private readonly Dictionary<string, double> _riskIndicators;
        private DateTime _lastUpdateTime;
        private readonly object _lockObj = new object();

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化风险控制矩阵
        /// </summary>
        /// <param name="initialRiskLevel">初始风险等级</param>
        public RiskControlMatrix(RiskLevel initialRiskLevel = RiskLevel.Moderate)
        {
            _currentRiskLevel = initialRiskLevel;
            _currentMarketState = MarketState.Normal;
            _riskIndicators = new Dictionary<string, double>();
            _lastUpdateTime = DateTime.Now;
            UpdateParameters();
        }

        #endregion

        #region 核心方法

        /// <summary>
        /// 根据市场数据更新市场状态
        /// </summary>
        public MarketState UpdateMarketState(
            double currentVolatility,
            double vixIndex,
            double marketDrawdown,
            double correlationBreakdown)
        {
            lock (_lockObj)
            {
                // 基于多个指标综合判断市场状态
                double riskScore = 0;
                
                // 波动率评分 (0-40分)
                if (currentVolatility < 0.01) riskScore += 0;
                else if (currentVolatility < 0.02) riskScore += 10;
                else if (currentVolatility < 0.03) riskScore += 20;
                else if (currentVolatility < 0.05) riskScore += 30;
                else riskScore += 40;
                
                // VIX指数评分 (0-30分)
                if (vixIndex < 15) riskScore += 0;
                else if (vixIndex < 20) riskScore += 10;
                else if (vixIndex < 30) riskScore += 20;
                else riskScore += 30;
                
                // 市场回撤评分 (0-20分)
                if (marketDrawdown < 0.05) riskScore += 0;
                else if (marketDrawdown < 0.1) riskScore += 10;
                else riskScore += 20;
                
                // 相关性破坏评分 (0-10分)
                if (correlationBreakdown < 0.3) riskScore += 0;
                else if (correlationBreakdown < 0.6) riskScore += 5;
                else riskScore += 10;
                
                // 根据总分判断市场状态
                if (riskScore <= 30)
                    _currentMarketState = MarketState.Normal;
                else if (riskScore <= 60)
                    _currentMarketState = MarketState.Warning;
                else
                    _currentMarketState = MarketState.Danger;
                
                // 更新风险指标记录
                _riskIndicators["Volatility"] = currentVolatility;
                _riskIndicators["VIX"] = vixIndex;
                _riskIndicators["Drawdown"] = marketDrawdown;
                _riskIndicators["CorrelationBreakdown"] = correlationBreakdown;
                _riskIndicators["RiskScore"] = riskScore;
                
                UpdateParameters();
                _lastUpdateTime = DateTime.Now;
                
                return _currentMarketState;
            }
        }

        /// <summary>
        /// 验证交易参数是否符合当前风控要求
        /// </summary>
        public ValidationResult ValidateTradeParameters(
            double positionSize,
            double leverage,
            double stopLoss,
            double gapRatio,
            double currentVaR,
            double bankruptcyProbability)
        {
            lock (_lockObj)
            {
                var result = new ValidationResult { IsValid = true };
                var p = _currentParameters;
                
                // 验证仓位大小
                if (positionSize < p.MinPositionSize || positionSize > p.MaxPositionSize)
                {
                    result.IsValid = false;
                    result.Violations.Add($"仓位大小 {positionSize:F2} 超出限制 [{p.MinPositionSize:F2}, {p.MaxPositionSize:F2}]");
                }
                
                // 验证杠杆
                if (leverage < p.MinLeverage || leverage > p.MaxLeverage)
                {
                    result.IsValid = false;
                    result.Violations.Add($"杠杆 {leverage:F0} 超出限制 [{p.MinLeverage:F0}, {p.MaxLeverage:F0}]");
                }
                
                // 验证止损
                if (stopLoss < p.MinStopLoss || stopLoss > p.MaxStopLoss)
                {
                    result.IsValid = false;
                    result.Violations.Add($"止损 {stopLoss:P2} 超出限制 [{p.MinStopLoss:P2}, {p.MaxStopLoss:P2}]");
                }
                
                // 验证敞口
                if (gapRatio < p.MinGapRatio || gapRatio > p.MaxGapRatio)
                {
                    result.IsValid = false;
                    result.Violations.Add($"敞口比例 {gapRatio:P2} 超出限制 [{p.MinGapRatio:P2}, {p.MaxGapRatio:P2}]");
                }
                
                // 验证VaR
                if (currentVaR > p.MaxVaR95)
                {
                    result.IsValid = false;
                    result.Violations.Add($"VaR {currentVaR:P2} 超过最大限制 {p.MaxVaR95:P2}");
                }
                
                // 验证破产概率
                if (bankruptcyProbability > p.MaxBankruptcyProbability)
                {
                    result.IsValid = false;
                    result.Violations.Add($"破产概率 {bankruptcyProbability:P2} 超过最大限制 {p.MaxBankruptcyProbability:P2}");
                }
                
                result.RiskLevel = _currentRiskLevel;
                result.MarketState = _currentMarketState;
                
                return result;
            }
        }

        /// <summary>
        /// 调整参数到合规范围
        /// </summary>
        public AdjustedParameters AdjustToCompliance(
            double positionSize,
            double leverage,
            double stopLoss,
            double gapRatio)
        {
            lock (_lockObj)
            {
                var p = _currentParameters;
                
                return new AdjustedParameters
                {
                    PositionSize = Math.Max(p.MinPositionSize, Math.Min(p.MaxPositionSize, positionSize)),
                    Leverage = Math.Max(p.MinLeverage, Math.Min(p.MaxLeverage, leverage)),
                    StopLoss = Math.Max(p.MinStopLoss, Math.Min(p.MaxStopLoss, stopLoss)),
                    GapRatio = Math.Max(p.MinGapRatio, Math.Min(p.MaxGapRatio, gapRatio)),
                    WasAdjusted = positionSize != Math.Max(p.MinPositionSize, Math.Min(p.MaxPositionSize, positionSize)) ||
                                  leverage != Math.Max(p.MinLeverage, Math.Min(p.MaxLeverage, leverage)) ||
                                  stopLoss != Math.Max(p.MinStopLoss, Math.Min(p.MaxStopLoss, stopLoss)) ||
                                  gapRatio != Math.Max(p.MinGapRatio, Math.Min(p.MaxGapRatio, gapRatio))
                };
            }
        }

        /// <summary>
        /// 获取当前风控参数
        /// </summary>
        public RiskParameters GetCurrentParameters()
        {
            lock (_lockObj)
            {
                return _currentParameters;
            }
        }

        /// <summary>
        /// 设置风险等级
        /// </summary>
        public void SetRiskLevel(RiskLevel level)
        {
            lock (_lockObj)
            {
                _currentRiskLevel = level;
                UpdateParameters();
            }
        }

        /// <summary>
        /// 切换到应急模式
        /// </summary>
        public void ActivateEmergencyMode()
        {
            lock (_lockObj)
            {
                _currentRiskLevel = RiskLevel.Emergency;
                UpdateParameters();
            }
        }

        /// <summary>
        /// 获取风险评估报告
        /// </summary>
        public RiskAssessmentReport GenerateRiskReport()
        {
            lock (_lockObj)
            {
                return new RiskAssessmentReport
                {
                    CurrentRiskLevel = _currentRiskLevel,
                    CurrentMarketState = _currentMarketState,
                    Parameters = _currentParameters,
                    RiskIndicators = new Dictionary<string, double>(_riskIndicators),
                    LastUpdateTime = _lastUpdateTime,
                    RecommendedActions = GenerateRecommendations()
                };
            }
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 更新当前参数
        /// </summary>
        private void UpdateParameters()
        {
            var key = (_currentRiskLevel, _currentMarketState);
            if (ParameterMatrix.TryGetValue(key, out var parameters))
            {
                _currentParameters = parameters;
            }
            else
            {
                // 默认使用稳健型正常市况参数
                _currentParameters = ParameterMatrix[(RiskLevel.Moderate, MarketState.Normal)];
            }
        }

        /// <summary>
        /// 生成风控建议
        /// </summary>
        private List<string> GenerateRecommendations()
        {
            var recommendations = new List<string>();
            
            if (_currentMarketState == MarketState.Danger)
            {
                recommendations.Add("市场处于危险状态，建议减少仓位或暂停交易");
            }
            
            if (_currentRiskLevel == RiskLevel.Aggressive && _currentMarketState != MarketState.Normal)
            {
                recommendations.Add("激进策略在非正常市况下风险极高，建议降低风险等级");
            }
            
            if (_riskIndicators.TryGetValue("VIX", out double vix) && vix > 30)
            {
                recommendations.Add($"VIX指数({vix:F1})异常高，市场恐慌情绪严重");
            }
            
            if (_riskIndicators.TryGetValue("Drawdown", out double drawdown) && drawdown > 0.15)
            {
                recommendations.Add($"市场回撤({drawdown:P1})较大，注意控制风险");
            }
            
            return recommendations;
        }

        #endregion

        #region 辅助类

        /// <summary>
        /// 验证结果
        /// </summary>
        public class ValidationResult
        {
            public bool IsValid { get; set; }
            public List<string> Violations { get; set; } = new List<string>();
            public RiskLevel RiskLevel { get; set; }
            public MarketState MarketState { get; set; }
        }

        /// <summary>
        /// 调整后的参数
        /// </summary>
        public class AdjustedParameters
        {
            public double PositionSize { get; set; }
            public double Leverage { get; set; }
            public double StopLoss { get; set; }
            public double GapRatio { get; set; }
            public bool WasAdjusted { get; set; }
        }

        /// <summary>
        /// 风险评估报告
        /// </summary>
        public class RiskAssessmentReport
        {
            public RiskLevel CurrentRiskLevel { get; set; }
            public MarketState CurrentMarketState { get; set; }
            public RiskParameters Parameters { get; set; }
            public Dictionary<string, double> RiskIndicators { get; set; }
            public DateTime LastUpdateTime { get; set; }
            public List<string> RecommendedActions { get; set; }
        }

        #endregion
    }
}